<template>
  <div class="forecast-container">
    <el-card shadow="never">
      <div class="control-panel">
        <span class="label">选择预测目标日期:</span>
        <el-date-picker
            v-model="targetDate"
            type="date"
            placeholder="选择日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            :disabled-date="disabledDate"
            style="margin: 0 20px;"
        />
        <el-button type="primary" :icon="Search" @click="fetchData" :loading="loading">开始预测</el-button>
      </div>
    </el-card>

    <el-card shadow="never" style="margin-top: 20px;">
      <div ref="chartRef" style="width: 100%; height: 600px;"></div>
      <el-empty v-if="!chartData && !loading" description="请选择日期并开始预测以生成图表"></el-empty>
    </el-card>
  </div>
</template>

<script setup>
import { ref, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { getForecastData } from '@/api/modules/forecast';
import { Search } from '@element-plus/icons-vue';

const colorPalette = [
  '#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de',
  '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'
];
// 用于存储每个产品ID对应的固定颜色
let productColorMap = {};

const targetDate = ref('');
const loading = ref(false);
const chartRef = ref(null);
let myChart = null;
let chartData = null;
let timer = null;

const disabledDate = (time) => {
  return time.getTime() < Date.now() - 8.64e7;
};

const fetchData = async () => {
  if (!targetDate.value) return;

  loading.value = true;
  if (timer) clearInterval(timer);
  if (myChart) myChart.clear();

  try {
    const res = await getForecastData(targetDate.value);
    chartData = res;

    productColorMap = {}; // 重置映射表
    if (chartData && chartData.productInfo) {
      const productIds = Object.keys(chartData.productInfo);
      productIds.forEach((id, index) => {
        productColorMap[id] = colorPalette[index % colorPalette.length];
      });
    }

    initChart();
  } catch (error) {
    console.error("获取预测数据失败", error);
    chartData = null;
    if (myChart) myChart.clear();
  } finally {
    loading.value = false;
  }
};

const initChart = () => {
  if (!chartRef.value || !chartData || !chartData.timeline || chartData.timeline.length === 0) {
    return;
  }

  if (myChart) myChart.dispose();
  myChart = echarts.init(chartRef.value);

  const productIds = Object.keys(chartData.series);
  let dayIndex = 0;

  const updateChart = () => {
    if (dayIndex >= chartData.timeline.length) {
      clearInterval(timer);
      timer = null;
      return;
    }

    // 将 productId 绑定到每个数据点上
    const currentDayData = productIds.map(id => ({
      value: chartData.series[id][dayIndex],
      name: chartData.productInfo[id] || id,
      productId: id
    })).sort((a, b) => a.value - b.value);

    const option = {
      title: {
        text: `生产预测动态排名 - ${chartData.timeline[dayIndex]}`,
        left: 'center'
      },
      grid: { left: '3%', right: '10%', bottom: '3%', containLabel: true },
      xAxis: { type: 'value', max: 'dataMax' },
      yAxis: {
        type: 'category',
        data: currentDayData.map(item => item.name),
        inverse: true,
        animationDuration: 300,
        animationDurationUpdate: 300,
      },
      series: [
        {
          realtimeSort: true,
          type: 'bar',
          data: currentDayData,
          label: { show: true, position: 'right', valueAnimation: true, formatter: '{c} 件' },
          itemStyle: {
            color: (params) => {
              // 根据 productId 从映射表中查找颜色，而不是根据 dataIndex
              const productId = params.data.productId;
              const color = productColorMap[productId] || '#cccccc'; // 如果找不到则给一个默认灰色
              return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                { offset: 0, color: echarts.color.lift(color, 0.4) },
                { offset: 1, color: color }
              ]);
            }
          },
        }
      ],
      animationDuration: 0,
      animationDurationUpdate: 800,
      animationEasing: 'linear',
      animationEasingUpdate: 'linear'
    };

    myChart.setOption(option);
    dayIndex++;
  };

  updateChart();
  timer = setInterval(updateChart, 10);
};

onBeforeUnmount(() => {
  if (timer) clearInterval(timer);
  if (myChart) myChart.dispose();
});
</script>

<style scoped>
.forecast-container {
  padding: 20px;
}
.control-panel {
  display: flex;
  align-items: center;
}
.label {
  font-size: 14px;
  color: #606266;
}
</style>
